package net.mikoo.seals.api.security;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.common.exceptions.UnauthorizedUserException;

import net.mikoo.seals.biz.common.WechatLoginParameter;
import net.mikoo.seals.biz.service.UserLoginServices;
import net.mikoo.seals.common.MD5;
import net.mikoo.seals.model.Party;
import net.sf.json.JSONObject;

public class OauthUserServiceImpl extends AbstractUserDetailsAuthenticationProvider {

	private static final Logger logger = Logger.getLogger(OauthUserServiceImpl.class);

	static final String LOGIN_FAILD_COUNT_KEY = "login:faild:count:%s";
	@Autowired
	private RedisTemplate<String, Object> objectRedisTemplate;

	@Autowired
	private UserLoginServices userLoginServices;

	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
	}

	@Override
	protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
		try {
			Party party = userLoginServices.wechatLogin(getloginParameter(authentication, username));
			clearLogiFaildCount(username);
			UserDetails userDetails = new CustomUserDetails(party);
			return userDetails;
		}catch(Exception e) {
			logger.error("", e);
			throw new UnauthorizedUserException(e.getMessage());
		}
	}
	
	private static WechatLoginParameter getloginParameter(UsernamePasswordAuthenticationToken authentication, String username) {
		assert authentication != null;
		WechatLoginParameter result = new WechatLoginParameter();
		try {
			JSONObject json = JSONObject.fromObject(JSONObject.fromObject(authentication).getString("details"));
			String password = MD5.calcMD5(JSONObject.fromObject(authentication).getString("credentials"));
			
			result.setIp(json.getString("ip"));
			result.setOpenId(json.getString("openId"));
			result.setPassword(password);
			result.setSmsCode(json.getString("smsCode"));
			result.setUnionId(json.getString("unionId"));
			result.setUsername(username);
		}catch(Exception e) {
			logger.error("", e);
			throw new UnauthorizedUserException("获取参数失败");
		}
		
		return result;
	}

	private void clearLogiFaildCount(String loginName) {
		objectRedisTemplate.delete(String.format(LOGIN_FAILD_COUNT_KEY, loginName));
	}
}
